package org.zjx.app.action.window;


import org.zjx.analysis.analyze.tap.*;
import org.zjx.app.action.AbstractWindowAction;
import org.zjx.command.entity.screen.Address;
import org.zjx.window.window.IWindow;

import java.awt.*;
import java.awt.event.KeyEvent;

public class TabAction extends AbstractWindowAction {
    private BaseTabAnalysis analysis;
    private final Address targetAddress;

    public  TabAction(IWindow targetWindow, Address targetAddress) {
        super(targetWindow, true);
        this.targetAddress = targetAddress;
        analysis();
    }

    private void analysis() {
        switch (targetAddress.getCity()) {
            case "长安城":
                analysis = new CACTabAnalysis(targetWindow);
                break;
            case "建邺城":
                analysis = new JYCTabAnalysis(targetWindow);
                break;
            case "地府":
                analysis = new DFTabAnalysis(targetWindow);
                break;
            case "大唐国境":
                analysis = new DTGJTabAnalysis(targetWindow);
                break;
            case "大唐境外":
                analysis = new DTJWTabAnalysis(targetWindow);
                break;
            case "大唐官府":
                analysis = new DTGFTabAnalysis(targetWindow);
                break;
            case "方寸山":
                analysis = new FCSTabAnalysis(targetWindow);
                break;
            case "傲来国":
                analysis = new ALGTabAnalysis(targetWindow);
                break;
            case "长寿村":
                analysis = new CSCTabAnalysis(targetWindow);
                break;
            case "东海海底":
                analysis = new DHHDTabAnalysis(targetWindow);
                break;
            case "东海湾":
                analysis = new DHWTabAnalysis(targetWindow);
                break;
            case "花果山":
                analysis = new HGSTabAnalysis(targetWindow);
                break;
            case "江南野外":
                analysis = new JNYWTabAnalysis(targetWindow);
                break;
            case "普陀山":
                analysis = new PTSTabAnalysis(targetWindow);
                break;
            case "凌霄宝殿":
                analysis = new LXBDTabAnalysis(targetWindow);
                break;
            case "宝象国":
                analysis = new BXGTabAnalysis(targetWindow);
                break;
            case "石头城":
                analysis = new STCTabAnalysis(targetWindow);
                break;
            case "天宫":
                analysis = new TGTabAnalysis(targetWindow);
                break;
            case "西梁女国":
                analysis = new XNNGTabAnalysis(targetWindow);
                break;
            case "五庄观":
                analysis = new WZGTabAnalysis(targetWindow);
                break;
            case "化生寺":
                analysis = new HSSTabAnalysis(targetWindow);
                break;
            case "女儿村":
                analysis = new NECTabAnalysis(targetWindow);
                break;
            case "朱紫国":
                analysis = new ZZGTabAnalysis(targetWindow);
                break;
            case "龙宫":
                analysis = new LGTabAnalysis(targetWindow);
                break;
            case "幻境花果山":
                analysis = new HJHGSTabAnalysis(targetWindow);
                break;
            case "留香阁":
                analysis = new LXGTabAnalysis(targetWindow);
                break;
            case "国子监书库":
                analysis = new GZJSKTabAnalysis(targetWindow);
                break;
            case "秦琼府":
                analysis = new QQFTabAnalysis(targetWindow);
                break;
            default:
                throw new IllegalArgumentException("Tab地图未采集：" + targetAddress.getCity());
        }
    }

    @Override
    public void open() {
        mouseAloofWindow(analysis.windowArea == null ? analysis.getOriginBounds() : analysis.windowArea);
        if (analysis.isOpened()) return;
        targetWindow.actions().hotkey(KeyEvent.VK_TAB).delay(200);
        targetWindow.flushScreenshot();
        analysis();
        open();
    }

    @Override
    public void close() {
        analysis();
        if (!analysis.isOpened()) return;
        targetWindow.actions().hotkey(KeyEvent.VK_TAB).delay(200);
        targetWindow.flushScreenshot();
        mouseAloofWindow(analysis.windowArea == null ? analysis.getOriginBounds() : analysis.windowArea);
        close();
    }

    @Override
    public void reSetWindow() {
        if (analysis.isTransborder()) {
            Rectangle from = analysis.conversion(analysis.windowArea, analysis.getRefImageArea());
            Rectangle to = analysis.conversion(analysis.getOriginBounds(), analysis.getRefImageArea());
            targetWindow.actions().drag(from.x, from.y, to.x, to.y).delay(100);
            targetWindow.flushScreenshot();
            analysis();
        }
    }

    @Override
    public void mouseAloofWindow(Rectangle rect) {
        if (analysis.mouseInRect(rect)) {
            Point safePoint = analysis.findLargestRemainingAreaCenter(rect);
            targetWindow.actions().gameMoveTo(safePoint.x, safePoint.y).delay(200);
            targetWindow.flushScreenshot();
            analysis();
        }
    }

    @Override
    protected void doExecute() throws Exception {
        open();
        if (!analysis.isOpened()) return;
        reSetWindow();
        Point targetLocation = new Point(targetAddress.getX(), targetAddress.getY());
        while (analysis.getLocation() == null || !locationNear(analysis.getLocation(),targetLocation)) {
            Point gameMousePoint = targetWindow.getExecutor().getMousePosition();
            if (analysis.getLocation() == null || gameMousePoint == null) {
                targetWindow.actions().moveTo(analysis.conversion(analysis.windowArea, analysis.getContentArea())).delay(100);
            } else {
                int offsetX = targetLocation.x - analysis.getLocation().x;
                int offsetY = analysis.getLocation().y - targetLocation.y;
                targetWindow.actions().moveTo(gameMousePoint.x + offsetX, gameMousePoint.y + offsetY).delay(100);
            }
            targetWindow.flushScreenshot();
            analysis();
        }
        targetWindow.actions().click(1).delay(200);
        close();
    }

    public boolean locationNear(Point point,Point point2) {
        if (point == null || point2 == null) return false;
        return Math.abs(point.x - point2.x) < 2 &&  Math.abs(point.y - point2.y) < 2;
    }
}
